package com.hk.core.autoconfigure.authentication.security.reactive;

import com.hk.core.authentication.api.UserPrincipal;
import com.hk.core.authentication.api.reactive.ReactiveSecurityContext;
import com.hk.core.authentication.security.reactive.ReactiveSpringSecurityContext;
import com.hk.core.autoconfigure.authentication.CommonSecurityAutoConfiguration;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import reactor.core.publisher.Mono;

import java.util.function.Function;

/**
 * @author Kevin
 * @date 2022-06-26 10:08
 */
@AutoConfiguration
@ConditionalOnClass(value = {ReactiveSecurityContext.class})
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
@ImportAutoConfiguration(value = {CommonSecurityAutoConfiguration.class})
public class ReactiveSecurityAuthenticationAutoConfiguration {

    /**
     * 可以在Spring 中定义 Function 函数式Bean，泛型参数要和定义的一样
     */
    @Bean
    public ReactiveSecurityContext reactiveSecurityContext(
            ObjectProvider<Function<UserPrincipal, Mono<? extends UserPrincipal>>> principalFunction) {
        var securityContext = new ReactiveSpringSecurityContext();
        var function = principalFunction.getIfAvailable(() -> Mono::just);
        securityContext.setFunction(function);
        return securityContext;
    }
}
